home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 147
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin
/
games
/
ippon
/
source.lzh
/
FuncEnemy
/
coverf.c
next >
Wrap
C/C++ Source or Header
|
2000-07-07
|
6KB
|
236 lines
/* coverf.c 前のカバーを開いて円形弾(を出す敵) */
#include <xsp2lib.h>
#include "../main.h"
#include "../player.h"
#include "../shot.h"
#include "../enemy.h"
#include "../eshot.h"
#include "../effect.h"
#include "../psearch.h"
#include "../sound.h"
#define PALET_MAIN 0x0700
#define HP_0 120 /* 耐久力 */
#define SPEED_1 2 /* 加速度 */
#define SPEED_1N 24 /* 加速度を足す回数 */
#define SPEED_2 3 /* 撤退時の加速度 */
#define SPEED_2N 28 /* 加速度を足す回数 */
enum {
MOVETO_INIT = 0, /* 初期状態 */
MOVETO_L, /* 左に移動 */
MOVETO_R
};
/* 関数プロトタイプ宣言 */
static short EnemyMoveCoverF (ENEMY *);
static void EnemyFreeCoverF (ENEMY *);
enum {
APPEAR_LEFT = 0, APPEAR_RIGHT
};
/* 初期化ルーチン */
void EnemyAllocCoverF (ENEMY * p)
{
if (SHORT_LX < 144) {
p->m_work5 = APPEAR_LEFT;
} else {
p->m_work5 = APPEAR_RIGHT;
}
p->vx = 0;
p->vy = 2 * 65536;
p->pt = obj_coverf;
p->info = PALET_MAIN | PRIORITY_BOSS;
p->hit_sx = 24; /* 自機ショットに対する当たり判定 */
p->hit_sy = 16;
p->hp = HP_0;
p->damage = 0;
p->flash = 0;
p->damage_mode = DAMAGE_PIERCE;
p->func_enemy_move = EnemyMoveCoverF;
p->func_enemy_free = EnemyFreeCoverF;
/* コア関連 */
p->core_info = PALET_CORE_BLUE | PRIORITY_BOSS;
p->core_pt = sp_core;
p->m_work = 0;
p->m_work2 = 0;
}
static short EnemyMoveCoverF (ENEMY * p)
{
/* 速度を足して上位ワード(固定整数部)だけ取り出す */
p->x = (p->lx += p->vx) >> 16;
p->y = (p->ly += p->vy) >> 16;
switch (p->m_work) {
case 0: /* 出現後減速 */
if (p->m_work2++ > 48) {
p->vy -= 2048;
}
if (SHORT_VY < 0) {
p->vy = 0;
p->m_work++;
p->m_work4 = MOVETO_INIT;
p->m_work2 = 0;
p->m_work3 = 0; /* 左右に移動した回数 */
p->s_work = 0;
}
break;
case 1:
/* まず移動処理 */
if (p->m_work4 == MOVETO_INIT) {
/* 初期状態なら */
if (p->m_work5 == APPEAR_LEFT)
p->m_work4 = MOVETO_R; /* 移動方向 */
else
p->m_work4 = MOVETO_L; /* 移動方向 */
p->m_work2 = 0;
}
if (p->m_work2 == 0) {
/* 初回なら */
signed short dx, dy;
signed short dx_table[3] =
{0, -64, 64};
signed short dy_table[6] =
{24, -16, 4, 24, -8, 8};
short m_work_table[3] =
{MOVETO_INIT, MOVETO_R, MOVETO_L};
p->m_work2 = !0;
/* 順に左→右→左へ移動 */
dx = SHORT_LX + dx_table[p->m_work4];
dy = SHORT_LY + dy_table[p->m_work4];
p->m_work4 = m_work_table[p->m_work4];
if (p->m_work3++ < 4) {
SubEnemyMoveToInit (p, dx, dy, SPEED_1, SPEED_1N);
} else {
SubEnemyMoveToInit (p, p->x, 256 + 64, SPEED_2, SPEED_2N);
p->m_work++; /* 撤退 */
}
} else {
/* 設定値に従って移動 */
if (SubEnemyMoveTo (p) < 0)
p->m_work2 = 0; /* 移動方向再設定 */
}
/* 次に攻撃処理 */
#define TIMER_SHOT_START 15
#define TIMER_SHOT_INTERVAL 20
#define SHOT_SPEED1 5
#define SHOT_SPEED2 7
p->s_work++;
if ((p->s_work < 10) && (p->pt < obj_coverf + 10))
p->pt++;
if ((p->s_work > TIMER_SHOT_START + TIMER_SHOT_INTERVAL * 6) && (p->pt > obj_coverf))
p->pt--;
switch (p->s_work) {
case TIMER_SHOT_START - 1:
p->s_angle = psearch (p->x, p->y); /* 自機の方向をサーチ */
break;
case TIMER_SHOT_START + TIMER_SHOT_INTERVAL * 0:
case TIMER_SHOT_START + TIMER_SHOT_INTERVAL * 2:
EshotAlloc (ESHOT_NRG03, SHORT_LX, SHORT_LY + 16, SHOT_SPEED1, p->s_angle - 24, 0);
EshotAlloc (ESHOT_NRG02, SHORT_LX, SHORT_LY + 16, SHOT_SPEED1, p->s_angle - 8, 0);
EshotAlloc (ESHOT_NRG02, SHORT_LX, SHORT_LY + 16, SHOT_SPEED1, p->s_angle + 8, 0);
EshotAlloc (ESHOT_NRG03, SHORT_LX, SHORT_LY + 16, SHOT_SPEED1, p->s_angle + 24, 0);
SoundSetSE (SE_ESHOT_M); /* 敵ショット音 */
break;
case TIMER_SHOT_START + TIMER_SHOT_INTERVAL * 1:
case TIMER_SHOT_START + TIMER_SHOT_INTERVAL * 3:
EshotAlloc (ESHOT_NRG04, SHORT_LX, SHORT_LY + 16, SHOT_SPEED2, p->s_angle - 24, 0);
EshotAlloc (ESHOT_NRG24N, SHORT_LX, SHORT_LY + 16, SHOT_SPEED2, p->s_angle - 8, 0);
EshotAlloc (ESHOT_NRG24N, SHORT_LX, SHORT_LY + 16, SHOT_SPEED2, p->s_angle + 8, 0);
EshotAlloc (ESHOT_NRG04, SHORT_LX, SHORT_LY + 16, SHOT_SPEED2, p->s_angle + 24, 0);
SoundSetSE (SE_ESHOT_M); /* 敵ショット音 */
break;
case TIMER_SHOT_START + TIMER_SHOT_INTERVAL * 7:
p->s_work = 0;
break;
default:
break;
}
break;
case 2:
/* 設定値に従って移動 */
if ((SubEnemyMoveTo (p) < 0) || (SHORT_LY > 256 + 32))
return (-1); /* 消去 */
if (p->pt > obj_coverf)
p->pt--;
break;
}
/* もし前回ダメージを受けたなら */
if (p->damage) {
p->hp -= p->damage;
p->damage = 0;
SoundSetSE (SE_DAMAGE); /* 敵ダメージ音 */
/* 白(or赤)フラッシュ処理 */
if (p->info == (PALET_MAIN | PRIORITY_BOSS)) {
if (p->hp < HP_PALET_RED)
p->info = PALET_RED | PRIORITY_BOSS;
else
p->info = PALET_DAMAGE | PRIORITY_BOSS;
} else {
p->info = PALET_MAIN | PRIORITY_BOSS;
}
/* 耐久力が0以下なら消去 */
if (p->hp <= 0) {
EffectAlloc (EFFECT_EXPL, 0, p->x, p->y); /* 爆発パターンを出現させる */
EffectAlloc (EFFECT_POINTS, POINTS_3000, p->x, p->y); /* 得点を出現させる */
SoundSetSE (SE_EXPL_M); /* 中ボス爆発音 */
return (-1);
}
} else {
/* 耐久力が少なくなったら赤フラッシュ */
if ((p->flash++ > TIMER_FLASH_RED) && (p->hp < HP_PALET_RED)) {
p->info = PALET_RED | PRIORITY_BOSS;
if (p->flash > TIMER_FLASH_NORMAL)
p->flash = 0;
} else {
p->info = PALET_MAIN | PRIORITY_BOSS;
}
}
xobj_set_st (p); /* 表示 */
/* コアの表示 */
p->core_x = p->x - 8; /* コアの中心は (-8,-8) ドットずれる */
p->core_y = p->y - 8;
xsp_set_st (&(p->core_x));
return (0);
}
/* 消去ルーチン */
static void EnemyFreeCoverF (ENEMY * p)
{
/* 刺さったショットの処理 */
if ((p->shot) && (p->shot->enemy) && (p->shot->enemy == p))
p->shot->status = SHOT_STATUS_NON;
}